package com.hnx.admin.system.service.impl;

import com.hnx.admin.api.log.LogHandler;
import com.hnx.admin.api.service.cache.CacheAPI;
import com.hnx.admin.api.service.login.LoginLogWriter;
import com.hnx.admin.json.RegionEntity;
import com.hnx.admin.redis.RedisCache;
import com.hnx.admin.system.domain.dto.user.EmpDTO;
import com.hnx.admin.system.domain.param.log.loginInfo.form.LoginInforForm;
import com.hnx.admin.system.domain.param.user.query.LoginBody;
import com.hnx.admin.system.domain.vo.user.UserDetailVO;
import com.hnx.admin.utils.AddressUtil;
import com.hnx.admin.utils.IPUtil;
import com.hnx.admin.utils.ServletUtil;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Objects;

/*
项目名称： core
创 建 人: 倔强的头发
创建日期： 2025/6/8   20:58:03 
描   述：登录日志类插入参数，插入数据库
特别注意：mapper类插入数据方法采用的是异步方式。

*/
@Slf4j
@Service
@RequiredArgsConstructor
public class LoginInforServiceImpl implements LoginLogWriter, CacheAPI {
    private final LogHandler<LoginInforForm> logHandlerFactory;
    private final RedisCache redisCache;
    @Override
    public void writeLog(Object obj, Integer status, String msg) {
        HttpServletRequest request = ServletUtil.getRequest();
        final UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        Browser browser = userAgent.getBrowser();
        OperatingSystem os = userAgent.getOperatingSystem();
        String clientIp = IPUtil.getClientIp(request);
            LoginBody loginBody = (LoginBody) obj;
            String region = "内网IP";
            if (AddressUtil.isValidPublicIp(clientIp)) {
                RegionEntity locationByIp = AddressUtil.getLocationByIp(clientIp);
                region = String.join(".", locationByIp.getCountry(), locationByIp.getProvince(), locationByIp.getCity());
            }
            LoginInforForm loginInforForm = LoginInforForm.builder()
                    .browser(browser.getName())
                    .ip(clientIp)
                    .msg(msg)
                    .os(os.getName())
                    .status(status)
                    .userName(StringUtils.hasText(loginBody.getUsername())?loginBody.getUsername():"")
                    .loginLocation(region)
                    .build();
                String token = loginBody.getUuid();
            if (StringUtils.hasText(token)) {
                UserDetailVO userDetailVO = redisCache.getCacheObject(getTokenKey(token), UserDetailVO.class);
                if (Objects.nonNull(userDetailVO)) {
                    EmpDTO emp = userDetailVO.getUserVO().getEmp();
                    loginInforForm.setUserId(emp.getUserId());
                    loginInforForm.setDeptId(emp.getDeptId());
                }
            }
        logHandlerFactory.asyncSaveLog(loginInforForm);
    }
}
